(module
  (import "env" "assert_eq_i32" (func $assert_eq_i32 (param i32 i32)))
  (start $main)
  (func $main (export "main")
    (call $assert_eq_i32 (call $fib (i32.const 0)) (i32.const 0))
    (call $assert_eq_i32 (call $fib (i32.const 1)) (i32.const 1))
    (call $assert_eq_i32 (call $fib (i32.const 2)) (i32.const 1))
    (call $assert_eq_i32 (call $fib (i32.const 3)) (i32.const 2))
    (call $assert_eq_i32 (call $fib (i32.const 4)) (i32.const 3))
    (call $assert_eq_i32 (call $fib (i32.const 5)) (i32.const 5))
    (call $assert_eq_i32 (call $fib (i32.const 6)) (i32.const 8))
    (call $assert_eq_i32 (call $fib (i32.const 7)) (i32.const 13))
    (call $assert_eq_i32 (call $fib (i32.const 8)) (i32.const 21))
    (call $assert_eq_i32 (call $fib (i32.const 9)) (i32.const 34))
    (call $assert_eq_i32 (call $fib (i32.const 17)) (i32.const 1597))
  )
  (; 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... ;)
  (func $fib (param $a i32) (result i32)
    (i32.const 0)
    (br_if 0 (i32.eqz (local.get $a)))
    (drop)

    (i32.const 1)
    (br_if 0 (i32.eq (local.get $a) (i32.const 1)))
    (br_if 0 (i32.eq (local.get $a) (i32.const 2)))
    (drop)

    (call $fib (i32.sub (local.get $a) (i32.const 1)))
    (call $fib (i32.sub (local.get $a) (i32.const 2)))

    (i32.add)
  )
)
